package com.wangzhen.spring.inject;

import com.wangzhen.spring.ioc.dependcy.entity.User;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

import java.util.Collection;

/**
 * 限定注入 演示示例
 * 背景：user和superUser都是User类型的bean
 *  @Autowired User user 注入的话，哪一个指定是primary，哪一个就会被注入；
 * 如果指定@Qualifier注解的话，就会按照名称注入
 */
public class LazyInjectDemo {

    // xml文件中配置的User，primary=true ---->实时注入
    @Autowired
    private User user;

    // 延迟注入：相当于是先注入一个proiver，等实际操作的时候需要通过provider#get方法获取实际对象之后，才能真正的执行操作
    // 这种方式 相当于是 @Autowired private Collection<User> user; 直接获取到了User类型的所有bean
    @Autowired
    private ObjectProvider<User> objectProvider;

    @Autowired
    private ObjectFactory<Collection<User>> users;

     public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LazyInjectDemo.class);
        // 使用注解方式驱动的AnnotationConfigApplicationContext，也可以加载xml配置
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(applicationContext);
        reader.loadBeanDefinitions("classpath:/META-INF/dependcy-lookup-context.xml");
        // 启动应用上下文
        applicationContext.refresh();
        // 获取UserHolder
        LazyInjectDemo demo = applicationContext.getBean(LazyInjectDemo.class);
        System.out.println("demo.user ="+demo.user);
        System.out.println("demo.objectProvider ="+demo.objectProvider);
        // 打印所有User类型的bean
        demo.objectProvider.forEach(System.out::println);
        // 通过ObjectFactory的方式获取所有User类型的bean，并打印
         System.out.println(demo.users);
        // 关闭应用上下文
        applicationContext.close();
    }

}
